home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_3.5 / Tutorials / ARexx / FunctionLibrary / rexxsample.doc < prev    next >
Encoding:
Text File  |  1998-10-03  |  5.6 KB  |  147 lines

  1. AREXX FUNCTION LIBRARIES
  2. ========================
  3.  
  4. ARexx maintains a list of function libraries and function hosts. The
  5. "rexxsupport.library" included in the ARexx distribution is an example of a
  6. function library, the ARexx resident process "REXX" is an example of
  7. a function host. Every function is passed through this list until a
  8. library or host responds to it. The list of function libraries and hosts is
  9. sorted by priority with the ARexx interpreter itself at priority -60
  10. near the end of the list. Priorities range from 100 to -100, inclusive.
  11.  
  12.  
  13. The query routine
  14. -----------------
  15. A function library must implement a special function known as the "query"
  16. entry point whose function definition looks like this:
  17.  
  18.     Result = Query(RexxMsg)
  19.      d0:a0           a0
  20.  
  21.     LONG Query(struct RexxMsg *);
  22.  
  23. The RexxMsg will hold the name of the function and up to 15 function
  24. arguments in the RexxMsg->rm_Args[..] array. The function name is stored
  25. in RexxMsg->rm_Args[0], the arguments follow in the slots 1 through 15.
  26. Name and arguments are stored as pointers to null-terminated strings.
  27. To find out how many arguments were passed to the query routine you
  28. should look at the lower eight bits of the RexxMsg->rm_Action entry:
  29.  
  30.     NumArgs = RexxMsg->rm_Action & 0xFF;
  31.  
  32. The query routine must preserve all registers except for d0/d1 and
  33. a0/a1 and return a result in registers d0 and a0. This is not feasible with
  34. all `C' compilers which will return results only in register d0. Your
  35. implementation may need to fall back on using assembly language "glue"
  36. code like this:
  37.  
  38.        xref _C_Query
  39.        xdef _Asm_Query
  40.  
  41.    _Asm_Query:
  42.  
  43.        clr.l  -(sp)     ; Make room for a pointer on the stack
  44.        move.l sp,a1     ; Store the address of the pointer in
  45.                         ; in register a1
  46.  
  47.        jsr    _C_Query  ; Invoke the `C' language function
  48.  
  49.        move.l (sp)+,a0  ; Load the pointer into register a0
  50.        rts              ; and return to ARexx
  51.  
  52. The `C' language query routine could then look like this (for
  53. the SAS/C compiler):
  54.  
  55.     LONG __asm
  56.     C_Query(register __a0 struct RexxMsg * msg,
  57.             register __a1 STRPTR *         res)
  58.     {
  59.         STRPTR result;
  60.  
  61.         result = "Result string";
  62.  
  63.         (*res) = CreateArgstring(result,strlen(result));
  64.         if((*res) != NULL)
  65.             return(0);
  66.         else
  67.             return(ERR10_003);
  68.     }
  69.  
  70.  
  71. What the query routine must do
  72. ------------------------------
  73. The query routine must decide whether it can handle the function and if so,
  74. if all the function parameters are in place and correct. If the function is
  75. not known to the library, it must return error code ERR10_001 (see
  76. "rexx/errors.h"). The function will then get passed to the next library or
  77. host on the list.
  78.  
  79.     NOTE: To find out if the function is known to your library
  80.           use a CASE-INSENSITIVE name comparison. You can make
  81.           no assumption on whether the name your function
  82.           receives will be written in upper case, lower case or
  83.           mixed case letters. The method of choice is to use
  84.           utility.library/Stricmp() for comparison.
  85.  
  86. If the function is known to your library, you need to check if the arguments
  87. are correct. The wrong number of arguments should be reported with error
  88. code ERR10_017. Further error checking is up to you, see "rexx/errors.h"
  89. for a list of errors known to ARexx.
  90.  
  91. If everything went well and no error occured your function should return 0
  92. in register d0 to indicate successful execution. This is what every `C'
  93. compiler will do with the "return" statement.
  94.  
  95.     NOTE: The query routine must use a non-standard way to return
  96.           function results.
  97.  
  98. What your query routine returns is generally only the error code. The
  99. functions the routine implements have to use a different technique to pass
  100. their results to ARexx. Any function result has to be converted into a
  101. string and needs to be wrapped into an ARexx string using
  102. rexxsyslib.library/CreateArgstring. The result of CreateArgstring must
  103. then be returned in register a0.
  104.  
  105.  
  106. Library design
  107. --------------
  108. A function library need not look different from any other Amiga shared
  109. library, it just has to implement the special query function in one of the
  110. library function slots. To use the library from ARexx you need to know the
  111. function offset, though. For example, if the query function were the first
  112. to follow the four standard library function entries (open, close, expunge,
  113. reserved) it would be located at offset -30.
  114.  
  115.  
  116. Usage from ARexx
  117. ----------------
  118. To make a function library available to ARexx you need to add it to the
  119. library list. This must happen before any of the library functions can be
  120. used, so a good place to do it is at the beginning of an ARexx script.
  121. Libraries are added using the built-in ARexx function ADDLIB which looks
  122. like this:
  123.  
  124.     Success = ADDLIB(Name,Priority,Offset,Version)
  125.  
  126. So, if you were to add the library "rexxsample.library" at priority 0 whose
  127. query function is located at offset -30 you were to use the following
  128. command in your ARexx script:
  129.  
  130.     addlib("rexxsample.library",0,-30,0)
  131.  
  132. Note that this will make the library known to ARexx but will not yet open
  133. it. To find out if the library is already known you can use the built-in
  134. ARexx function SHOW which looks like this:
  135.  
  136.    Success = SHOW(Option,Name,Pad)
  137.  
  138. The Pad parameter is not used here and may be omitted. To find out if the
  139. library "rexxsample.library" is already known to ARexx and to add it if it
  140. is not you would use the following commands:
  141.  
  142.     if ~show(libraries,"rexxsample.library") then do
  143.         if ~addlib("rexxsample.library",0,-30,0) then do
  144.             say "Could not add rexxsample.library"
  145.         end
  146.     end
  147.